package com.ocp.socket.server.service;

import com.alibaba.fastjson.JSON;
import com.ocp.socket.busi.dataAripUtils.bean.DataAirpVo;
import com.ocp.socket.busi.dataAripUtils.mapper.DataAirpUtilsMapper;
import com.ocp.socket.busi.dataMilkUtils.bean.DataMilkVo;
import com.ocp.socket.busi.dataMilkUtils.bean.QueryDataMilkVo;
import com.ocp.socket.busi.dataMilkUtils.mapper.DataMilkUtilsMapper;
import com.ocp.socket.busi.utils.mapper.UtilsMapper;
import com.ocp.socket.busi.utils.service.IDataUtilService;
import com.ocp.socket.busi.warnItem.bean.BaseWarnItem;
import com.ocp.socket.busi.warnItem.mapper.BaseWarnItemMapper;
import com.ocp.socket.busi.warnMsg.bean.BaseWarnMsg;
import com.ocp.socket.busi.warnMsg.mapper.BaseWarnMsgMapper;
import com.ocp.socket.common.Constants;
import com.ocp.socket.common.bean.DevInfo;
import com.ocp.socket.common.enums.DeviceWarnEnum;
import com.ocp.socket.common.enums.MsgTypeEnum;
import com.ocp.socket.common.enums.WarnCodeEnum;
import com.ocp.socket.common.utils.CommonUtils;
import com.ocp.socket.common.utils.RedisUtil;
import com.ocp.socket.common.utils.SessionUtil;
import com.ocp.socket.common.utils.TableUtils;
import com.ocp.socket.server.vo.DataVo;
import com.ocp.socket.server.vo.MessageVo;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Auther: zhangzh
 * @Date: 2019/3/3 07:01
 * @Description: 气压报文处理
 * @Version: 1.0.0
 */
@Service("airpService")
@Transactional
public class AirpService {

    private final Logger logger = (Logger) LoggerFactory.getLogger(getClass());

    @Value("${msgDataDb}")
    private String msgDataDb;

    @Value("${airpMsg}")
    private String airp;

    @Value("${milkMsg}")
    private String milk;

    @Autowired
    UtilsMapper utilsMapper;

    @Autowired
    DataMilkUtilsMapper dataMilkUtilsMapper;

    @Autowired
    DataAirpUtilsMapper dataAirpUtilsMapper;

    @Autowired
    BaseWarnMsgMapper baseWarnMsgMapper;

    @Autowired
    BaseWarnItemMapper baseWarnItemMapper;
    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IDataUtilService dataUtilService;

    /******
     * 保存气压的报文信息到数据库
     * @param messageVo
     * @return
     */
    public MessageVo savePressureData(MessageVo messageVo, IoSession session) {
        if (messageVo.getDataVoMap().size() < 1) {
            logger.info("当前气压没有配置线路！");
            messageVo.setReturnCode("1");
            messageVo.setReturnMsg("当前气压没有配置线路！");
            return messageVo;
        }
        //获取设备信息
        DevInfo devInfo = (DevInfo) session.getAttribute(Constants.ATTRIBUTE_KEY_AUTH);
        //牧场的id
        Integer orgId = devInfo.getOrgId();
        //当前气压记录表
        String nowAirpTableName = TableUtils.getDataTableName(msgDataDb, airp, orgId,
                messageVo.getDataTime().substring(0, 8));
        //气压状态表
        String airpStatTableName = TableUtils.getDataStatTableName(airp, orgId);
        //挤奶清洗状态当前状态表
        String milkStatTableName = TableUtils.getDataStatTableName(milk, orgId);
        //创建温度记录表
        dataUtilService.createDataTableIfNotExist(nowAirpTableName, airp);
        //创建当前温度状态表
        dataUtilService.createStatTableIfNotExist(airpStatTableName, airp);
        //创建当前挤奶清洗状态表
        dataUtilService.createStatTableIfNotExist(milkStatTableName, milk);
        //报警信息MAP
        Map<String, String> baseWarnMsgMap = new HashMap<String, String>();
        //报警信息稳定时长MAP
        Map<String, Integer> baseWarnMsgTimesMap = new HashMap<String, Integer>();
        //报警项信息MAP
        Map<String, BaseWarnItem> baseWarnItemMap = new HashMap<String, BaseWarnItem>();
        //根据奶厅查询当前奶厅挤奶清洗的状态
        QueryDataMilkVo queryDataMilkVo = new QueryDataMilkVo();
        queryDataMilkVo.setHallId(devInfo.getHallId());
        queryDataMilkVo.setVal("-1");
        DataMilkVo dataMilkVo = dataMilkUtilsMapper.getInfoByTableName(milkStatTableName, queryDataMilkVo);
        //如果是旧数据
        if (!messageVo.isNewDataFlag()) {
            Map<String, DataVo> dataVoMap = messageVo.getDataVoMap();
            List<DataAirpVo> datas = new ArrayList<>();
            DataAirpVo dataAirpVo = null;
            DataVo dataVo;
            for (String key : dataVoMap.keySet()) {
                dataVo = dataVoMap.get(key);
                dataAirpVo = new DataAirpVo();
                dataAirpVo.setHallId(devInfo.getHallId());
                dataAirpVo.setDataTime(messageVo.getDataTime());
                dataAirpVo.setLineCode(key);
                dataAirpVo.setVal(Double.valueOf(dataVo.getVal()));
                dataAirpVo.setUnit(dataVo.getUnit());
                dataAirpVo.setRunStat(dataVo.getRunStat());
                dataAirpVo.setRunStatDesc(dataVo.getRunStatDesc());
                dataAirpVo.setSnNo(messageVo.getSn());
                datas.add(dataAirpVo);
            }
            try {
                dataAirpUtilsMapper.insertDataAirps(nowAirpTableName, datas);
            } catch (Exception e) {
                logger.error("====批量插入气压数据报错:{}", e.getMessage());
            }
            return messageVo;
        }
        //奶厅下已有且未结束的报警信息
        List<BaseWarnMsg> baseWarnMsgList = baseWarnMsgMapper.getBaseWarnMsgListByMilkHallId(devInfo.getHallId());
        for (BaseWarnMsg baseWarnMsg : baseWarnMsgList) {
            baseWarnMsgMap.put(baseWarnMsg.getWarnCode(), baseWarnMsg.getId());
            baseWarnMsgTimesMap.put(baseWarnMsg.getWarnCode(), baseWarnMsg.getEndTimes());
        }
        baseWarnMsgList.clear();

        //根据奶厅查询已配置的报警信息项
        List<BaseWarnItem> baseWarnItemList = baseWarnItemMapper.getBaseWarnItemListByMilkHallId(devInfo.getHallId());
        for (BaseWarnItem baseWarnItem : baseWarnItemList) {
            baseWarnItemMap.put(baseWarnItem.getWarnCode(), baseWarnItem);
        }
        baseWarnItemList.clear();

        /****
         * W011 挤奶时真空压力波动大
         * 奶厅已配置该报警
         * 报警关键因素 真空压力
         */
        if (baseWarnItemMap.get(WarnCodeEnum.W011.getWarnCode()) != null && messageVo.getDataVoMap().get("L01") != null) {
            Double t1Val = Double.valueOf(messageVo.getDataVoMap().get("L01").getVal());

            //挤奶 并且超过20分钟
            if (dataMilkVo != null && "L01".equals(dataMilkVo.getLineCode()) && baseWarnItemMap.get(WarnCodeEnum.W011.getWarnCode()).getIgnoreTimes() < dataMilkVo.getRunTimes()) {
                if (t1Val < baseWarnItemMap.get(WarnCodeEnum.W011.getWarnCode()).getMinVal() || t1Val > baseWarnItemMap.get(WarnCodeEnum.W011.getWarnCode()).getMaxVal()) {
                    messageVo.getDataVoMap().get("L01").setRunStat("0");
                    messageVo.getDataVoMap().get("L01").setRunStatDesc("运行异常");
                    if (baseWarnMsgMap.get(WarnCodeEnum.W011.getWarnCode()) == null) {
                        CommonUtils.insertBaseWarnMsg(session, baseWarnMsgMapper, WarnCodeEnum.W011.getWarnCode(), baseWarnItemMap, messageVo, devInfo, messageVo.getSn(), "L01", redisUtil,DeviceWarnEnum.AIRP.getDeviceCode());
                    } else {
                        baseWarnMsgMapper.initWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W011.getWarnCode()));
                    }
                } else {
                    if (baseWarnMsgMap.get(WarnCodeEnum.W011.getWarnCode()) != null) {
                        if (baseWarnMsgTimesMap !=null && baseWarnMsgTimesMap.get(WarnCodeEnum.W011.getWarnCode()) > 10) {
                            CommonUtils.updateBaseWarnMsgEndTimeById(session, baseWarnMsgMapper, baseWarnMsgMap.get(WarnCodeEnum.W011.getWarnCode()), messageVo.getDataTime(), devInfo.getSnNo(), devInfo.getOrgId());
                        } else {
                            baseWarnMsgMapper.addWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W011.getWarnCode()));
                        }
                    }
                }
            }
        }

        /****
         * W013 空压机压力小
         * 奶厅已配置该报警
         * 报警关键因素 空压机压
         */
        if (baseWarnItemMap.get(WarnCodeEnum.W013.getWarnCode()) != null && messageVo.getDataVoMap().get(WarnCodeEnum.W013.getWarnCode()) != null) {
            Double t2Val = Double.valueOf(messageVo.getDataVoMap().get("L02").getVal());
            //有挤奶信号或者清洗信号时
            if (dataMilkVo != null && "L01".equals(dataMilkVo.getLineCode()) || "L02".equals(dataMilkVo.getLineCode())) {
                if (t2Val < baseWarnItemMap.get(WarnCodeEnum.W013.getWarnCode()).getMinVal()) {
                    messageVo.getDataVoMap().get("L02").setRunStat("0");
                    messageVo.getDataVoMap().get("L02").setRunStatDesc("运行异常");
                    if (baseWarnMsgMap.get(WarnCodeEnum.W013.getWarnCode()) == null) {
                        CommonUtils.insertBaseWarnMsg(session, baseWarnMsgMapper, WarnCodeEnum.W013.getWarnCode(), baseWarnItemMap, messageVo, devInfo, messageVo.getSn(), "L02", redisUtil,DeviceWarnEnum.AIRP.getDeviceCode());
                    } else {
                        baseWarnMsgMapper.initWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W013.getWarnCode()));
                    }
                } else {
                    if (baseWarnMsgMap.get(WarnCodeEnum.W013.getWarnCode()) != null) {
                        if (baseWarnMsgTimesMap !=null && baseWarnMsgTimesMap.get(WarnCodeEnum.W013.getWarnCode()) > 10) {
                            CommonUtils.updateBaseWarnMsgEndTimeById(session, baseWarnMsgMapper, baseWarnMsgMap.get(WarnCodeEnum.W013.getWarnCode()), messageVo.getDataTime(), devInfo.getSnNo(), devInfo.getOrgId());
                        } else {
                            baseWarnMsgMapper.addWarnMsgEndTimes(baseWarnMsgMap.get(WarnCodeEnum.W013.getWarnCode()));
                        }
                    }
                }
            }
        }
        Map<String, DataVo> dataVoMap = messageVo.getDataVoMap();
        DataAirpVo dataAirpVo = null;
        List<DataAirpVo> returnValList = new ArrayList<DataAirpVo>();
        DataVo dataVo;
        for (String key : dataVoMap.keySet()) {
            dataVo = dataVoMap.get(key);
            //添加气压报警
            if ("L01".equals(key)) {
                addAirpMsgOpenShortWarn(key, Double.valueOf(dataVo.getVal()), messageVo, devInfo, baseWarnItemMap, baseWarnMsgMap, baseWarnMsgTimesMap, session);
            }
            dataAirpVo = new DataAirpVo();
            dataAirpVo.setHallId(devInfo.getHallId());
            dataAirpVo.setDataTime(messageVo.getDataTime());
            dataAirpVo.setLineCode(key);
            if (dataMilkVo != null) {
                dataAirpVo.setMilkCleanLine(dataMilkVo.getLineCode());
            }
            dataAirpVo.setVal(Double.valueOf(dataVo.getVal()));
            dataAirpVo.setUnit(dataVo.getUnit());
            dataAirpVo.setRunStat(dataVo.getRunStat());
            dataAirpVo.setRunStatDesc(dataVo.getRunStatDesc());
            dataAirpVo.setSnNo(messageVo.getSn());
            dataAirpUtilsMapper.insertDataAirp(airpStatTableName, dataAirpVo);
            returnValList.add(dataAirpVo);
        }
        try {
            //批量插入压力数据
            dataAirpUtilsMapper.insertDataAirps(nowAirpTableName, returnValList);
        } catch (Exception e) {
            logger.error("===批量插入气压数据报错:{}", e.getMessage());
        }
        //发送消息
        logger.debug("气压发送app的Json:" + JSON.toJSON(returnValList).toString());
        SessionUtil.sendAppUserMsgByOrgId(session, devInfo.getOrgId(), CommonUtils.toMsg(MsgTypeEnum.E.getTypeCode(), messageVo.getSn(), messageVo.getDataTime(), JSON.toJSON(returnValList).toString()));
        returnValList.clear();
        //发送该牧场的报警总数
        Map<String, Integer> warnCntMap = new HashMap<String, Integer>();
        warnCntMap.put("orgWarnCnt", baseWarnMsgMapper.getWarnMsgCntByMilkOrgId(devInfo.getOrgId()));
        SessionUtil.sendAppUserMsgByOrgId(session, devInfo.getOrgId(), CommonUtils.toMsg(MsgTypeEnum.J.getTypeCode(), messageVo.getSn(), messageVo.getDataTime(), JSON.toJSON(warnCntMap).toString()));
        return messageVo;
    }

    /*******
     * 添加气压报警
     * @param lineCode
     * @param val
     * @param messageVo
     * @param devInfo
     * @param baseWarnItemMap
     * @param baseWarnMsgMap
     * @param baseWarnMsgTimesMap
     * @param session
     */
    private void addAirpMsgOpenShortWarn(String lineCode, Double val, MessageVo messageVo, DevInfo devInfo, Map<String, BaseWarnItem> baseWarnItemMap, Map<String, String> baseWarnMsgMap, Map<String, Integer> baseWarnMsgTimesMap, IoSession session) {
        String warnCode = null;
        if ("L01".equals(lineCode)) {
            warnCode = "W051";
        }

        if (baseWarnItemMap != null && baseWarnItemMap.get(warnCode) != null && val < baseWarnItemMap.get(warnCode).getMinVal()) {
            messageVo.getDataVoMap().get(lineCode).setRunStat("0");
            messageVo.getDataVoMap().get(lineCode).setRunStatDesc("运行异常");
            if (baseWarnMsgMap.get(warnCode) == null) {
                CommonUtils.insertBaseWarnMsg(session, baseWarnMsgMapper, warnCode, baseWarnItemMap, messageVo, devInfo, messageVo.getSn(), lineCode, redisUtil,DeviceWarnEnum.AIRP.getDeviceCode());
            } else {
                baseWarnMsgMapper.initWarnMsgEndTimes(baseWarnMsgMap.get(warnCode));
            }
        } else {
            if (baseWarnMsgMap.get(warnCode) != null) {
                if (baseWarnMsgTimesMap !=null && baseWarnMsgTimesMap.get(warnCode) > 10) {
                    CommonUtils.updateBaseWarnMsgEndTimeById(session, baseWarnMsgMapper, baseWarnMsgMap.get(warnCode), messageVo.getDataTime(), devInfo.getSnNo(), devInfo.getOrgId());
                } else {
                    baseWarnMsgMapper.addWarnMsgEndTimes(baseWarnMsgMap.get(warnCode));
                }
            }
        }
    }


}
